Lab 04

Functions, Pictures, and Mastermind
Due by 6pm on Tuesday, September 26

The purpose of this lab is to:

Part 1 - Picture this

Create a program called sketchy.py that draws the picture you designed on your prelab using either the picture module or the picture2 module. Your program should use at least one function (Make a flower; make rays on the sun; make gerbil -- anything you might want to have more than one copy of in your picture); you might use x and y coordinates of the location as parameters of the function. If you are going to draw in the function you should also make the canvas one argument of the function.

Here are a few of the things you can do with the picture module:

To adjust the pen width, use the setPenWidth function. To position and draw with the pen, use the setPosition, setDirection, rotate and drawForward functions. To draw simple shapes, you can use functions like drawCircle, drawCircleFill, drawRect, drawRectFill, etc. Use setFillColor to change the fill color used when creating shapes. Use setOutlineColor to change the color of shape edges and pen lines.

You can read more about different picture functions here

Some of the best sketches will be shown in class to general acclaim.

Part 2 -- Function Practice

For this part you need to write a program functionPractice.py that has the following as its main( ) function:

def main():
      done = False
      while not done:
            x = eval(input( "x: "))
            if x == 0:
                  done = True
            else:
                  print(square(x))
                  checkEvenOdd(x)
                  print(reverse(x))

Of course, this is just our usual input loop that reads numbers typed by the user until the user exits with input 0. For each non-zero input there are three functions called; your job is to add these three functions to the program. They are

Function reverse( ) should be the only one of these that challenges you. One way to do this is to convert x to a string, reverse its digits, and then convert the result back into an integer. Here is a numerical algorithm for this function. Make variable result which starts at 0. Go into a loop until x is 0. At each step multiply result by 10 and add the rightmost digit of x, which is x%10. Divide x by 10 to eliminate its rightmost digit, and go around the loop again. If you do this on paper with a number like 325 you'll see how this algorithm works.

Notice that two of these functions return something; the middle one does something. Take a moment to look at how the code for the function and the code for the call both differ when a function returns something as opposed to doing something.

Part 3 - Mind Mastery

Mastermind is a neat (although often frustrating) puzzle game. It works a something like this: There are two players. One player (your program) is the codemaker, the other (the user) is the codebreaker. The codemaker chooses a sequence of four colored pegs, out of a possible six colors (red, blue, green, yellow, orange, and purple). He may repeat colors and place them in any order he wishes. This sequence is hidden from the codebreaker. The codebreaker has 10 chances to guess the sequence. The codebreaker places colored pegs down to indicate each of her guesses. After each guess, the codemaker is required to reveal certain information about how close the guess was to the actual hidden sequence.

Describe the Problem:
Write a program called master.py that allows the user to play a text-based version of the fantastic game Mastermind.
input: repeatedly get guesses from the user, until they either guess the code, or run out of guesses.
goal: generate a random code, and correctly provide the user with feedback on their guesses.


Understand the Problem:
The trickiest part of this game is determining how to provide feedback on the codebreaker's guesses. In particular, next to each guess that the codebreaker makes, the codemaker places up to four clue pegs. Each clue peg is either black or white. Each black peg indicates a correct color in a correct spot. Each white peg indicates a correct color in an incorrect spot. No indication is given as to which clue corresponds to which guess.

For example, suppose that the code is RYGY (red yellow green yellow). Then the guess GRGY (green red green yellow) would cause the codemaker to put down 2 black pegs (since guesses 3 and 4 were correct) and 1 white peg (since the red guess was correct, but out of place). Note that no peg was given for guess 1 even though there was a green in the code; this is because that green had already been "counted" (a black peg had been given for that one).

As another example, again using RYGY as our code, the guess YBBB would generate 1 white peg and 0 black; yellow appears twice in the code, but the guess only contains one yellow peg. Likewise, for the guess BRRR, only 1 white peg is given; there is an R in the code, but only one. Below is a table with guesses and the correponding number of black and white pegs given for that guess (still assuming the code is RYGY).

guess black pegs white pegs
YYYY 2 0
YRYR 0 3
BBPO 0 0
PGYR 0 3
YYYG 1 2
RYGY 4 0

Check here for an online graphical version of the game (where their red pegs are our black pegs).

A sample run of our text-based program may look like this:

Sample output

    %python3 master.py
    
    I have a 4 letter code, made from 6 colours.
    The colours are R, G, B, Y, P, or O.

	Your guess: GGGG
    Not quite. You get 0 black pegs, 0 white pegs.

        Your guess: YYYY
    Not quite. You get 1 black pegs, 0 white pegs.

        Your guess: YOYO
    Not quite. You get 0 black pegs, 2 white pegs.

        Your guess: PPYO
    Not quite. You get 1 black pegs, 2 white pegs.

        Your guess: POYB
    Not quite. You get 1 black pegs, 3 white pegs.

        Your guess: PBOY
    You win! Aren't you smart.


Design an Algorithm:
Once you understand how the game works, you should design a pseudocode plan of attack. The general steps are:

Some of these steps are straight-forward, but certainly it would be worth your while to write down an approach to randomly generating the code, and giving the clue. Here is our recommendation for the latter algorithm is as follows:

Implement a Design:
Now that you have some of the kinks worked out in theory, it is time to write your program master.py.

You may assume the user always provides a guess with the available colors, and always in uppercase.

Make and use an integer constant NUM_TURNS that represents the number of allowable turns and set this to 10..

To generate the code, write a function

    generateCode() 

that generates the codemaker's code (and returns it as a String to the caller). That is, this function should randomly generate 4 colored pegs, selected from R, B, G, Y, O, and P, and return it as a 4-letter string. You'll want to use the random methods as discussed in lab03 in order to randomly generate a color for each peg. In particular, you'll generate an integer between 0 and 5 inclusive. You can use this as an index into the string "RBGYOP" of all of the color symbols to get your next color.

Test your generateCode function thoroughly before continuing. Once it's working, write a second function

    evaluateGuess( code, guess )

that returns the numbers of white and black clue pegs according to the given guess and code. Keep going around the guess loop until the number of black pegs is 4 or the user has name NUM_TURNS guesses.

Note that you can "change" the ith character in a string s to an 'x' as follows:

    s = s[0:i] + "x" + s[i+1:]

Also note that s[j:] is the substring of s from position j to the end. Similarly, s[:j] denotes the substring of s from the beginning up to (but not including) j.



Test the Program:
It is hard to test your program with a random code that you don't know. One trick that helps is to have your generateCode( ) function return a code that you do know. After generateCode( ) is debugged and you are sure you are generating random codes; insert into the function a new first line:
            return "RYGY"
which will make the function always return the string "RYGY". You can then tell if your evaluateGuess( ) function is giving correct answers. Remember to remove (or comment out) this line before you hand in your program.


To make this program easier to grade (and to help with debugging) have it print the code before you start guessing. Of course, when you make a commercial version to sell you will want to delete this, but hand in a version that prints the code.

Handin

If you followed the Honor Code in this assignment, make an HonorCode file that says

I affirm that I have adhered to the Honor Code in this assignment.

You now just need to electronically handin all your files. As a reminder

 
     % cd             # changes to your home directory
     % cd cs150       # goes to your cs150 folder
     % handin         # starts the handin program
                      # class is 150
                      # assignment is 4
                      # file/directory is lab04
     % lshand         # should show that you've handed in something

You can also specify the options to handin from the command line

 
     % cd ~/cs150     # goes to your cs150 folder
     % handin -c 150 -a 4 lab04

File Checklist


You should have submitted the following files:
	sketchy.py
	functionPractice.py
	mastermind.py
	picture.py or picture2.py (for ease of grading)
HonorCode (with the Honor Pledge)


Last edited August 2017 T. Wexler, A. Sharp, C. Taylor, R. Geitz